﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Coslen.Framework.Helpers
{
    public static class PagingHelpers
    {
        private static MvcHtmlString BuildForm(string actionName, string controllerName, string innerHtml, string formId)
        {
            TagBuilder tagBuilder = new TagBuilder("form");
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);

            tagBuilder.Attributes["action"] = url.Action(actionName, controllerName);

            tagBuilder.Attributes["id"] = formId;
            tagBuilder.Attributes["method"] = HtmlHelper.GetFormMethodString(FormMethod.Post);
            tagBuilder.InnerHtml = innerHtml;

            return new MvcHtmlString(tagBuilder.ToString());

        }

        private static string BuildReference(string text, int page, int currentPage, Func<int, string> pageUrl)
        {
            TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag
            tag.MergeAttribute("href", pageUrl(page));
            tag.InnerHtml = text.ToString();
            if (page == currentPage)
                tag.AddCssClass("selected");

            return tag.ToString();
        }

        private static MvcHtmlString TextBox(string fieldName, string value, string className)
        {
            if (string.IsNullOrWhiteSpace(className))
            {
                className = "text-box";
            }

            TagBuilder tagBuilder = new TagBuilder("Input");

            tagBuilder.MergeAttribute("id", fieldName);
            tagBuilder.MergeAttribute("name", fieldName);
            tagBuilder.MergeAttribute("type", "Text");
            tagBuilder.AddCssClass(className);
            tagBuilder.MergeAttribute("data-val", "true");
            tagBuilder.MergeAttribute("data-val-regex-pattern", "true");
            tagBuilder.MergeAttribute("data-val", "true");
            tagBuilder.MergeAttribute("value", value);

            TagBuilder validator = new TagBuilder("span");

            validator.MergeAttribute("data-valmsg-for", fieldName);
            validator.MergeAttribute("data-valmsg-replace", "true");
            validator.MergeAttribute("class", "field-validation-valid");

            return new MvcHtmlString(string.Concat(tagBuilder.ToString(), validator.ToString()));
        }

        public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
        {
            StringBuilder result = new StringBuilder();

            int numberOfItemsToShow = 5;

            result.Append(BuildReference("<<", 1, -1, pageUrl));
            result.Append(BuildReference("<", pagingInfo.CurrentPage <= (numberOfItemsToShow * 2) ? 1 : pagingInfo.CurrentPage - (numberOfItemsToShow * 2), -1, pageUrl));

            int firstPage = pagingInfo.CurrentPage - numberOfItemsToShow;
            firstPage = firstPage < 1 ? 1 : firstPage;

            int lastPage = pagingInfo.CurrentPage + numberOfItemsToShow;
            lastPage = lastPage > pagingInfo.TotalPages ? pagingInfo.TotalPages : lastPage;

            // Before the current input box
            for (int i = firstPage; i < pagingInfo.CurrentPage; i++)
            {
                result.Append(BuildReference(i.ToString(), i, pagingInfo.CurrentPage, pageUrl));
            }

            result.Append(BuildReference(pagingInfo.CurrentPage.ToString(), pagingInfo.CurrentPage, pagingInfo.CurrentPage, pageUrl));

            // After the current input box
            for (int i = pagingInfo.CurrentPage + 1; i <= lastPage; i++)
            {
                result.Append(BuildReference(i.ToString(), i, pagingInfo.CurrentPage, pageUrl));
            }

            result.Append(BuildReference(">", pagingInfo.CurrentPage + (numberOfItemsToShow * 2) >= pagingInfo.TotalPages ? pagingInfo.TotalPages : pagingInfo.CurrentPage + (numberOfItemsToShow * 2), -1, pageUrl));
            result.Append(BuildReference(">>", pagingInfo.TotalPages, -1, pageUrl));

            return MvcHtmlString.Create(result.ToString());
        }
    }
}
